package cn.jrainbow.base;

import java.io.Serializable;  
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.jrainbow.base.IBaseDao;

/**
 * BaseDaoImpl 定义DAO的通用操作的实现
 * 
 * @author JRainbow 
 */
public class BaseDao<T,PK extends Serializable> extends HibernateDaoSupport implements IBaseDao<T,PK> {

	private Class<T> clazz;

	public BaseDao() {
		ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
		clazz = (Class<T>) type.getActualTypeArguments()[0];
		
	}

	/** 
     * 给HibernateDaoSupport注入一个SessionFactory. 
     * 如果是xml的话，是直接把sesionFactory注入就行了。而这里需要一个额外的setter方法。 
     */  
    @Autowired  
    public void setMySessionFactory(SessionFactory sessionFactory){  
        super.setSessionFactory(sessionFactory);  
    }

	
    public void save(T entity) {           
    	getHibernateTemplate().save(entity);   
    }   
     
    public void update(T entity) {
    	getHibernateTemplate().update(entity);
	}
  
    
    public void delete(T entity) {   
    	getHibernateTemplate().delete(entity);
    }   
    
     
    public void deleteById(PK id) {  

        getHibernateTemplate().delete(this.findById(id));  
    }  
       
    
    public void saveOrUpdate(T entity) {   
    	getHibernateTemplate().saveOrUpdate(entity);    
    }   
  
    
    public T findById(PK id) {   
    	 return (T) getHibernateTemplate().get(clazz, id);   
    }   
  
    
   
    @SuppressWarnings("unchecked")
	public List<T> findByHql(String hql) {  
        return getHibernateTemplate().find(hql);  
    }  
  
   
    @SuppressWarnings(value = { "unchecked" })
    public List<T> findByPage(final String hql, final Integer start,final Integer limit) {        
    	return getHibernateTemplate().execute(new HibernateCallback() {   
            public Object doInHibernate(Session session)   
                    throws HibernateException, SQLException {   
                Query query = session.createQuery(hql);   
                query.setFirstResult(start);   
                query.setMaxResults(limit);  
                return query.list();   
            }   
        }); 
    }

	public Long getTotal(String hql) {
		return (Long) getHibernateTemplate().find("select count(*) " + hql).get(0);
	}      
}
